//
// Created by antler on 2018/12/6.
//

#include "Rect.h"

#include <algorithm>

Rect Rect::ZERO = Rect();

Rect *Rect::create() {
    return new(std::nothrow)Rect();
}

Rect *Rect::createWith(int x, int y, int width, int height) {
    return new(std::nothrow)Rect(x, y, width, height);
}

Rect *Rect::createWith(const Point &origin, const Size &size) {
    return new(std::nothrow)Rect(origin.x, origin.y, size.width, size.height);
}

Rect *Rect::createWith(const Rect &rect) {
    return new(std::nothrow)Rect(rect);
}

Rect::Rect() {
    x = y = 0;
    width = height = 0;
}

Rect::Rect(int x, int y, int width, int height) {
    this->x = x;
    this->y = y;
    this->width = width;
    this->height = height;
}

bool Rect::isEmpty() const {
    return width <= 0 || height <= 0;
}

Point Rect::tl() {
    return Point(x, y);
}

Point Rect::br() {
    return Point(x + width, y + height);
}

bool Rect::contains(const Point &point) {
    if (x < point.x && point.x < x + width) {
        if (y < point.y && point.y < y + height) {
            return true;
        }
    }
    return false;
}

Rect Rect::unionRect(const Rect &other) {
    int l = std::min(x, other.x);
    int t = std::min(y, other.y);
    int r = std::max(x + width, other.x + other.width);
    int b = std::max(y + height, other.y + other.height);

    return Rect(l, t, r - l, b - t);
}

Rect Rect::intersectRect(const Rect &other) {
    int l = std::max(x, other.x);
    int t = std::max(y, other.y);
    int r = std::min(x + width, other.x + other.width);
    int b = std::min(y + height, other.y + other.height);

    if (l < r && t < b) {
        return Rect(l, t, r - l, b - t);
    }
    return Rect();
}


